package cj.utils.weixin;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import org.springframework.util.StringUtils;

import cj.utils.Constants;
import cj.utils.MD5Security;

/**
 * 微信摇一摇红包
 * @author Administrator
 * 1、申请红包接口权限：登录摇一摇周边商户后台https://zb.weixin.qq.com ,进入开发者支持，申请开通摇一摇红包组件接口;
 * 2、红包预下单：调用微信支付的api进行红包预下单，告知需要发放的红包金额，人数，生成红包ticket；
 * 3、创建活动并录入红包信息：调用摇周边平台的api录入创建红包活动并录入信息，传入预下单时生成的红包ticket；
 * 4、调用jsapi抽红包：在摇出的页面中通过调用jsapi抽红包，抽中红包的用户可以拆红包；
 * 5、调用以上接口时，红包提供商户和红包发放商户公众号要求一致。
 */
public class YHongBaoWeiXinUtil {
	
	private final static String appid = " ";// 应用ID
	private final static String appsecret = " ";// 应用密钥
	private final static String partner = " ";// 微信支付商户号
	private final static String partnerkey = " ";// 财付通初始密Key
	private final static String KEYSTORE_FILE = "E:/apiclient_cert.p12";
	private final static String KEYSTORE_PASSWORD = "10035097";
	
	//Step1===红包预下单接口===hbpreorder
	public static String invokeHbpreorder() throws Exception
	{
		String hbpreorderPostUrl="https://api.mch.weixin.qq.com/mmpaymkttransfers/hbpreorder";
		//签名
		String sign = "E1EE61A91C8E90F299DE6AE075D60A2D";
		//商户订单号
		String mch_billno = "0010010404201411170000046545";
		//商户号
		String mch_id = "10000097";
		//公众账号appid
		String wxappid = "wxcbda96de0b165486";
		//商户名称
		String send_name = "哈哈哈";
		//红包类型(NORMAL-普通红包；GROUP-裂变红包(可分享红包给好友，无关注公众号能力)。)
		String hb_type = "NORMAL";
		//授权商户号
		String auth_mchid = "10000098";
		//授权商户APPID
		String auth_appid = "wx7777777";
		//总金额
		String total_amount = "200";
		//红包金额设置方式(红包金额设置方式，只对裂变红包生效。 ALL_RAND —全部随机)
		String amt_type = "ALL_RAND";
		//红包发放总人数
		String total_num = "3";
		//红包祝福语
		String wishing = "恭喜发财";
		//活动名称
		String act_name = "新年红包";
		//备注
		String remark = "新年红包";
		
		/**风控设置(用于管控接口风险。具体值如下：
		 * NORMAL—正常情况；
		 * IGN_FREQ_LMT—忽略防刷限制，强制发放；
		 * IGN_DAY_LMT—忽略单用户日限额限制，强制发放；
		 * IGN_FREQ_DAY_LMT—忽略防刷和单用户日限额限制，强制发放；如无特殊要求，
		 * 请设为NORMAL。若忽略某项风险控制，可能造成资金损失，请谨慎使用。)
		 */
		String risk_cntl = "NORMAL";
		//随机字符串
		String nonce_str = "50780e0cca98c8c8e814883e5caa672e";
		
		//request XML
		StringBuffer requestContent=new StringBuffer("<xml>")
			.append("<sign><![CDATA["+sign+"]></sign>")
			.append("<mch_billno><![CDATA["+mch_billno+"]]></mch_billno>")
			.append("<mch_id><![CDATA["+mch_id+"]]></mch_id>")
			.append("<wxappid><![CDATA["+wxappid+"]]></wxappid>")
			.append("<send_name><![CDATA["+send_name+"]]></send_name>")
			.append("<hb_type><![CDATA["+hb_type+"]]></hb_type>")
			.append("<auth_mchid><![CDATA["+auth_mchid+"]]></auth_mchid>")
			.append("<auth_appid><![CDATA["+auth_appid+"]]></auth_appid>")
			.append("<total_amount><![CDATA["+total_amount+"]]></total_amount>")
			.append("<amt_type><![CDATA["+amt_type+"]]></amt_type>")
			.append("<total_num><![CDATA["+total_num+"]]></total_num>")
			.append("<wishing><![CDATA["+wishing+"]]></wishing>")
			.append("<act_name><![CDATA["+act_name+"]]></act_name>")
			.append("<remark><![CDATA["+remark+"]]></remark>")
			.append("<risk_cntl><![CDATA["+risk_cntl+"]]></risk_cntl>")
			.append("<nonce_str><![CDATA["+nonce_str+"]]></nonce_str>")
			.append("</xml>");
		
		//请求远端微信Http接口
		byte[] xml = HttpsWenXinUtil.post(hbpreorderPostUrl, requestContent.toString(), Constants.charset);
		return new String(xml, Constants.charset);
	}
	
	/**
	 * 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 sign
	 * @throws Exception 
	 */
	private static String createSign(Map<String, Object> map) throws Exception {
		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		for (Map.Entry<String, Object> m : map.entrySet()) {
			packageParams.put(m.getKey(), m.getValue().toString());
		}

		StringBuffer sb = new StringBuffer();
		Set<?> es = packageParams.entrySet();
		Iterator<?> it = es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String k = (String) entry.getKey();
			String v = (String) entry.getValue();
			if (!StringUtils.isEmpty(v) && !"sign".equals(k) && !"key".equals(k)) {
				sb.append(k + "=" + v + "&");
			}
		}
		sb.append("key=" + partnerkey);
		 
		
		String sign = MD5Security.md5(sb.toString()).toUpperCase();
		return sign;
	}
	
	/**
	 * 创建XML
	 */
	private static String createXML(Map<String, Object> map){
		String xml = "<xml>";
		Set<String> set = map.keySet();
		Iterator<String> i = set.iterator();
		while(i.hasNext()){
			String str = i.next();
			xml+="<"+str+">"+"<![CDATA["+map.get(str)+"]]>"+"</"+str+">";
		}
		xml+="</xml>";
		return xml;
	}

//	public static String doSendMoney(String url, String data) throws Exception {
//		KeyStore keyStore  = KeyStore.getInstance("PKCS12");
//		  FileInputStream instream = new FileInputStream(new File(KEYSTORE_FILE));//P12文件目录
////		InputStream instream = YHongBaoWeiXinUtil.class.getResourceAsStream("/apiclient_cert.p12");
//        try {
//            keyStore.load(instream, KEYSTORE_PASSWORD.toCharArray());//这里写密码..默认是你的MCHID
//        } finally {
//            instream.close();
//        }
//        // Trust own CA and all self-signed certs
//        SSLContext sslcontext = SSLContexts.custom()
//                .loadKeyMaterial(keyStore, KEYSTORE_PASSWORD.toCharArray())//这里也是写密码的
//                .build();
//        // Allow TLSv1 protocol only
//        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
//        		SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
//        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
//        try {
//        	HttpPost httpost = new HttpPost(url); // 设置响应头信息
//        	httpost.addHeader("Connection", "keep-alive");
//        	httpost.addHeader("Accept", "*/*");
//        	httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
//        	httpost.addHeader("Host", "api.mch.weixin.qq.com");
//        	httpost.addHeader("X-Requested-With", "XMLHttpRequest");
//        	httpost.addHeader("Cache-Control", "max-age=0");
//        	httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
//    		httpost.setEntity(new StringEntity(data, "UTF-8"));
//            CloseableHttpResponse response = httpclient.execute(httpost);
//            try {
//                HttpEntity entity = response.getEntity();
//                String jsonStr = toStringInfo(response.getEntity(),"UTF-8");
//                
//                //微信返回的报文时GBK，直接使用httpcore解析乱码
//              //  String jsonStr = EntityUtils.toString(response.getEntity(),"UTF-8");
//                EntityUtils.consume(entity);
//               return jsonStr;
//            } finally {
//                response.close();
//            }
//        } finally {
//            httpclient.close();
//        }
//	}
//	
//	private static String toStringInfo(HttpEntity entity, String defaultCharset) throws Exception, IOException{
//		final InputStream instream = entity.getContent();
//	    if (instream == null) {
//	        return null;
//	    }
//	    try {
//	        Args.check(entity.getContentLength() <= Integer.MAX_VALUE,
//	                "HTTP entity too large to be buffered in memory");
//	        int i = (int)entity.getContentLength();
//	        if (i < 0) {
//	            i = 4096;
//	        }
//	        Charset charset = null;
//	        
//	        if (charset == null) {
//	            charset = Charset.forName(defaultCharset);
//	        }
//	        if (charset == null) {
//	            charset = HTTP.DEF_CONTENT_CHARSET;
//	        }
//	        final Reader reader = new InputStreamReader(instream, charset);
//	        final CharArrayBuffer buffer = new CharArrayBuffer(i);
//	        final char[] tmp = new char[1024];
//	        int l;
//	        while((l = reader.read(tmp)) != -1) {
//	            buffer.append(tmp, 0, l);
//	        }
//	        return buffer.toString();
//	    } finally {
//	        instream.close();
//	    }
//	}
	
	public static void main(String[] args) throws Exception
	{
		String resultStr = invokeHbpreorder();
		System.out.println(resultStr);
	}
}
